{
  "nbformat": 4,
  "nbformat_minor": 0,
  "metadata": {
    "colab": {
      "name": "mandelbrot.ipynb",
      "version": "0.3.2",
      "provenance": [],
      "private_outputs": true,
      "collapsed_sections": [],
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "HhR5048dZ3e1"
      },
      "source": [
        "##### Copyright 2019 The TensorFlow Authors."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "f0A2utIXbPc5",
        "cellView": "form",
        "colab": {}
      },
      "source": [
        "#@title Licensed under the Apache License, Version 2.0 (the \"License\");\n",
        "# you may not use this file except in compliance with the License.\n",
        "# You may obtain a copy of the License at\n",
        "#\n",
        "# https://www.apache.org/licenses/LICENSE-2.0\n",
        "#\n",
        "# Unless required by applicable law or agreed to in writing, software\n",
        "# distributed under the License is distributed on an \"AS IS\" BASIS,\n",
        "# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n",
        "# See the License for the specific language governing permissions and\n",
        "# limitations under the License."
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "1qF0JETfbfIR"
      },
      "source": [
        "# Mandelbrot set"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "p8Z8Pb5nbtZ3"
      },
      "source": [
        "<table class=\"tfo-notebook-buttons\" align=\"left\">\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://colab.research.google.com/github/tensorflow/examples/blob/master/community/en/mandelbrot.ipynb\"><img src=\"https://www.tensorflow.org/images/colab_logo_32px.png\" />Run in Google Colab</a>\n",
        "  </td>\n",
        "  <td>\n",
        "    <a target=\"_blank\" href=\"https://github.com/tensorflow/examples/blob/master/community/en/mandelbrot.ipynb\"><img src=\"https://www.tensorflow.org/images/GitHub-Mark-32px.png\" />View source on GitHub</a>\n",
        "  </td>\n",
        "</table>"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "lqPLlJWqcSFZ"
      },
      "source": [
        "Visualizing the [Mandelbrot set](https://en.wikipedia.org/wiki/Mandelbrot_set) doesn't have anything to do with machine learning, but it makes for a fun example of how one can use TensorFlow for general mathematics. This is actually a pretty naive implementation of the visualization, but it makes the point. (A more elaborate implementation may be provided down the line to produce more truly beautiful images.)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "80RrFh7EcnLT"
      },
      "source": [
        "## Basic setup\n",
        "\n",
        "You'll need a few imports to get started."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "XOLK5q1Wa1Dc",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "try:\n",
        "  # %tensorflow_version only exists in Colab.\n",
        "  %tensorflow_version 2.x\n",
        "except Exception:\n",
        "  pass\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "xc-QSV_SdEG4",
        "colab": {}
      },
      "source": [
        "from __future__ import absolute_import, division, print_function, unicode_literals\n",
        "\n",
        "# Import libraries for simulation\n",
        "import tensorflow as tf\n",
        "import numpy as np\n",
        "\n",
        "# Imports for visualization\n",
        "import PIL.Image\n",
        "from io import BytesIO\n",
        "from IPython.display import clear_output, Image, display\n"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "mP5YEOuTieH0"
      },
      "source": [
        "\n",
        "Now you'll define a function to actually display the image once you have iteration counts."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "_q_HC5cGhX4h",
        "colab": {}
      },
      "source": [
        "def DisplayFractal(a, fmt='jpeg'):\n",
        "  \"\"\"Display an array of iteration counts as a\n",
        "     colorful picture of a fractal.\"\"\"\n",
        "  a_cyclic = (6.28*a/20.0).reshape(list(a.shape)+[1])\n",
        "  img = np.concatenate([10+20*np.cos(a_cyclic),\n",
        "                        30+50*np.sin(a_cyclic),\n",
        "                        155-80*np.cos(a_cyclic)], 2)\n",
        "  img[a==a.max()] = 0\n",
        "  a = img\n",
        "  a = np.uint8(np.clip(a, 0, 255))\n",
        "  f = BytesIO()\n",
        "  PIL.Image.fromarray(a).save(f, fmt)\n",
        "  display(Image(data=f.getvalue()))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "xEptO88QikEM"
      },
      "source": [
        "# Variable initialization\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "_NFwmNL5iqBd"
      },
      "source": [
        "\n",
        "It's handy that you can mix NumPy and TensorFlow."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "fHu_sT7chbg_",
        "colab": {}
      },
      "source": [
        "# Use NumPy to create a 2D array of complex numbers\n",
        "\n",
        "Y, X = np.mgrid[-1.3:1.3:0.005, -2:1:0.005]\n",
        "Z = X+1j*Y"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "u7SsqtHqivVW"
      },
      "source": [
        "\n",
        "Now you define and initialize TensorFlow tensors."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "UpGYdAWQhhCN",
        "colab": {}
      },
      "source": [
        "xs = tf.constant(Z.astype(np.complex64))\n",
        "zs = tf.Variable(xs)\n",
        "not_diverged =tf.Variable(tf.zeros_like(xs, tf.bool))\n",
        "ns = tf.Variable(tf.zeros_like(xs, tf.float32))"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "ao_esnw4jAJp"
      },
      "source": [
        "# Defining and running the computation\n",
        "\n",
        "Now you specify the computation and run it for a couple hundred steps"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "twC_FiUSiN8s",
        "colab": {}
      },
      "source": [
        "for i in range(200): \n",
        "  # Compute the new values of z: z^2 + x\n",
        "  zs = zs*zs+xs\n",
        "  # Have we diverged with this new value?\n",
        "  not_diverged = tf.abs(zs) < 4\n",
        "  # Operation to update the iteration count.\n",
        "  #\n",
        "  # Note: We keep computing zs after they diverge! This\n",
        "  #       is very wasteful! There are better, if a little\n",
        "  #       less simple, ways to do this.\n",
        "  #\n",
        "  ns = ns + tf.cast( not_diverged, tf.float32)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "vf54ZY-Iowbr",
        "colab_type": "text"
      },
      "source": [
        "Convert from tensor to numpy array for visualization"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "id": "woSnv6gJoz7m",
        "colab_type": "code",
        "colab": {}
      },
      "source": [
        "ns = ns.numpy()"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "vfoDAWtijLKd"
      },
      "source": [
        "\n",
        "Let's see what you've got."
      ]
    },
    {
      "cell_type": "code",
      "metadata": {
        "colab_type": "code",
        "id": "8qqfdbuOiV90",
        "colab": {}
      },
      "source": [
        "DisplayFractal(ns)"
      ],
      "execution_count": 0,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "colab_type": "text",
        "id": "vB-3S5cFjVYQ"
      },
      "source": [
        "Not bad!"
      ]
    }
  ]
}